home *** CD-ROM | disk | FTP | other *** search
/ Gold Medal Software 2 / Gold Medal Software Volume 2 (Gold Medal) (1994).iso / prog / asm_0_m.arj / LOCATE.ASM < prev    next >
Assembly Source File  |  1986-06-05  |  13KB  |  231 lines

  1. CODE_SEG        SEGMENT
  2.         ASSUME  CS:CODE_SEG,DS:CODE_SEG,ES:CODE_SEG
  3.         ORG     100H                    ;Start off right for a .COM file
  4. ENTRY:  JMP     LOCATE                  ;Skip over Data area
  5.  
  6.         COPY_RIGHT DB '(C)1985 S.Holzner'       ;Author's Mark
  7.         FOUND_MSG DB 13,10,13,10,'FOUND IN $'   ;Like it says
  8.         LEN             DW 1                    ;The file length (low word)
  9.         PATH_LEN        DW 0                    ;Length of Path.Dat
  10.         NUMBER          DW 0                    ;Number of bytes read from file
  11.         EXTRA_PATHS     DB 0                    ;=1 if we open & use Path.Dat
  12.         OLD_BX          DW 0                    ;Save pointer to path at CS:DBH
  13.         OLD_SI          DW 0                    ;Save SI as pointer also
  14.         START_FLAG      DB 0                    ;For searches in Path.Dat
  15.         PATH_DAT        DB "\PATH.DAT",0        ;ASCIIZ string of Path.Dat
  16.  
  17. LOCATE  PROC    NEAR            ;Here we go
  18.  
  19.         MOV     DX,0B0H         ;Move Disk Transfer Area to CS:0B0H
  20.         MOV     AH,1AH          ;Matched file information goes there
  21.         INT     21H
  22.  
  23.         MOV     DI,5CH          ;Use CS:5CH to put '*.*'0 at for search
  24.         CALL    PUT             ; in current directory
  25.         MOV     DX,5CH          ;Point to '*.*'0 for search
  26.         MOV     AH,4EH          ; and find first matching file
  27.         INT     21H             ;Match now at DTA, 0B0H
  28. LOOP:                           ;Loop over matches now
  29.         MOV     BX,0CAH         ;Get file length, came from match
  30.         MOV     DX,[BX]
  31.         MOV     LEN,DX          ;Store in Len
  32.         CMP     DX,60*1024      ;Don't write over stack, allow < 64K files
  33.         JB      NOT_BIG         ;Range extender (Find > 127 bytes ahead)
  34.         JMP     FIND
  35. NOT_BIG:CMP     DX,0            ;Was this a 0 length file (disk dir or label)?
  36.         JA      FILE_OK         ;No, go on and read it
  37.         JMP     FIND            ;Yes, find next file and skip this one
  38. FILE_OK:CALL    READ_FILE       ;Get the file into memory
  39.         MOV     CX,NUMBER       ;Prepare to loop over all read bytes
  40.         MOV     DI,OFFSET PATHS+300     ;File starts at Offset Paths+300
  41. SEARCH:                                 ;Use Repne Scasb & DI to search for the
  42.         MOV     BX,82H          ;first letter of the string, which is at CS:82H
  43.         MOV     AL,BYTE PTR [BX]        ;Load into AL for Repne Scasb
  44. REPNE   SCASB                           ;Find first letter
  45.         JCXZ    FIND            ;If out of file to search, find next file
  46.         MOV     BX,80H          ;How many chars in string? Get from CS:80H
  47.         XOR     DX,DX           ;Set DX to zero
  48.         MOV     DL,[BX]         ;Get # of chars in string
  49.         DEC     DX              ;Get rid of space typed after 'Locate'
  50.         MOV     SI,83H          ;Search from second typed letter (1st matched)
  51. CPLOOP: DEC     DX              ;Loop counter
  52.         CMPSB                   ;See how far we get until no match
  53.         JZ      CPLOOP
  54.         DEC     DI              ;At end, reset DI (Scasb increments 1 too much)
  55.         CMP     DX,0            ;If DX is not zero, all letters did not match
  56.         JA      SEARCH          ;If not a match, go back and get next one
  57.         LEA     DX,FOUND_MSG    ;FILE HAS BEEN FOUND, so say so.
  58.         MOV     AH,9            ;Request string search
  59.         INT     21H
  60.         MOV     AH,2            ;Now to print filename. Without Path.Dat, at
  61.         MOV     BX,0DBH         ; CS:CEH, with Path.Dat at CS:DBH
  62.         CMP     EXTRA_PATHS,1   ; Using Path.Dat yet?
  63.         JE      PRINT           ;Yes, print
  64.         MOV     BX,0CEH         ;No, reset BX to point to CS:CEH
  65. PRINT:  MOV     DL,[BX]         ;Print out the filename until 0 found
  66.         CMP     DL,0            ;Is it 0?
  67.         JE      MORE            ;If yes,print out sample at More:
  68.         INT     21H             ;Print filename character
  69.         INC     BX              ;Point to next character
  70.         JMP     PRINT           ;Go back relentlessly until done
  71. MORE:   PUSH    DI              ;Save DI,BX,CX
  72.         PUSH    BX
  73.         PUSH    CX
  74.         MOV     CX,40           ;Prepare to type out total of 40 characters
  75.         MOV     AH,2            ;With Int 21H service 2
  76.         MOV     DL,':'          ;But first, add ':' to filename
  77.         INT     21H             ;And a carriage return linefeed
  78.         MOV     DL,13
  79.         INT     21H
  80.         MOV     DL,10
  81.         INT     21H
  82.         SUB     DI,20           ;DI points to end of found string, move back
  83.         MOV     BX,OFFSET PATHS+300     ;Beginning of file
  84.         CMP     DI,BX           ;If before beginning, start at beginning
  85.         JA      GO
  86.         MOV     DI,BX
  87. GO:     ADD     BX,LEN          ;Now BX=end of file (to check if we're past it)
  88. SHOW:   MOV     DL,[DI]         ;Get character from file
  89.         INC     DI              ;And point to next one
  90.         CMP     DI,BX           ;Past end?
  91.         JA      SHOWS_OVER      ;Yes, jump out, look for next match
  92.         CMP     DL,30           ;Unprintable character?
  93.         JA      POK             ;No, OK
  94.         MOV     DL,' '          ;Yes, make it a space
  95. POK:    INT     21H             ;Print Character
  96.         LOOP    SHOW            ;And return for the next one
  97. SHOWS_OVER:                     ;End of printout
  98.         POP     CX              ;Restore the registers used above
  99.         POP     BX
  100.         POP     DI
  101.         JMP     SEARCH          ;Return to search more of the file
  102. FIND:   CALL    FIND_FILE       ;This file done, find next match
  103.         CMP     AL,18           ;AL=18 --> no match
  104.         JE      OUT             ;And so we leave
  105.         JMP     LOOP            ;If match found, go back once again
  106. OUT:    INT     20H             ;End of Main Program
  107. LOCATE  ENDP
  108.  
  109. PUT     PROC    NEAR                    ;This little gem puts a '*.*'0
  110.         MOV     BYTE PTR [DI],'*'       ;Wherever you want it--just send
  111.         MOV     BYTE PTR [DI+1],'.'     ; it a value in DI. '*.*'0 is used as
  112.         MOV     BYTE PTR [DI+2],'*'     ; a universal wilcard in searches
  113.         MOV     BYTE PTR [DI+3],0
  114.         RET
  115. PUT     ENDP
  116.  
  117. WS      PROC    NEAR                    ;Strip the bits for WordStar
  118.         CMP     CX,0                    ;If there is a length of 0, e.g.
  119.         JE      FIN                     ;Directory entries, etc. do nothing.
  120. WSLOOP: AND BYTE PTR [BX],127           ;Set top bit to zero
  121.         INC     BX                      ;Point to next unsuspecting byte
  122.         LOOP    WSLOOP                  ;And get it too.
  123. FIN:    RET                             ;To use, send this program BX and CX
  124. WS      ENDP
  125.  
  126. FIND_FILE       PROC    NEAR    ;The file finder
  127.         MOV     AH,4FH          ;Try service 4FH, find next match, first
  128.         INT     21H
  129.         CMP     AL,18           ;AL = 18 --> no match
  130.         JE      CHECK           ;Range extender.
  131.         JMP     NEW
  132. CHECK:  CMP     EXTRA_PATHS,1   ;Have we used path.Dat?
  133.         JE      NEXT_PATH       ;Yes, get next path, this one's used up
  134.         INC     EXTRA_PATHS     ;No, set it to 1
  135.         MOV     AX,3D00H        ;Request file opening for Path.Dat
  136.         LEA     DX,PATH_DAT     ;Point to '\PATH.DAT'0
  137.         INT     21H
  138.         JNC     READ            ;If there was a carry, Path.Dat not found
  139. DONE:   MOV     AL,18           ;And so we exit with AL=18
  140.         JMP     END
  141. READ:   MOV     CX,300          ;Assume the max length for Path.Dat, 300.
  142.         MOV     BX,AX           ;Move found file handle into BX for read
  143.         MOV     AH,3FH          ;Set up for file read
  144.         LEA     DX,PATHS        ;Put the file at location Paths (at end)
  145.         INT     21H             ;Read in the file
  146.         ADD     AX,OFFSET PATHS         ;Full offset of end of Path.Dat
  147.         MOV     PATH_LEN,AX     ;Get Path.Dat end point for loop
  148.         MOV     AH,3EH          ;Now close the file
  149.         INT     21H             ;Close file
  150.         MOV     OLD_SI,OFFSET PATHS     ;Save for future path-readings
  151.         MOV     CX,300                  ;Get ready to Un-WordStar
  152.         MOV     BX,OFFSET PATHS         ;300 bytes at location Paths
  153.         CALL    WS                      ;Strip high bit for WS
  154. NEXT_PATH:              ;Come here to find next path to search for files
  155.         MOV     SI,OLD_SI               ;Point to start of next path
  156.         MOV     DI,5CH  ;Move will be to CS:5CH for '\path\*.*0' file find
  157.         MOV     BX,0DBH ;Also to CS:DBH; will assemble full path & filename
  158.         MOV     START_FLAG,0    ;Start the path search
  159. CHAR:   CMP     SI,PATH_LEN     ;Past end of possible path names?
  160.         JGE     DONE            ;Yes, we're done. Leave with AL=18
  161.         CMP     BYTE PTR [SI],30        ;Carriage return or linefeed?
  162.         JB      NEXT                    ;Yes, get next char
  163.         MOV     START_FLAG,1            ;First char, stop skipping chars
  164.         MOV     AL,[SI]                 ;Get char from Path.Dat
  165.         MOV     [BX],AL                 ;Move char to DBH
  166.         INC     BX                      ;And increment to next location there
  167.         MOVSB                           ;Also move to 5CH area
  168.         JMP     CHAR                    ;And go back for more
  169. NEXT:   CMP     START_FLAG,1    ;Bad char, have we been reading a real pathname?
  170.         JE      PDONE           ;Yes, we've reached the end of it.
  171.         INC     SI              ;No, keep skipping chars to find pathname
  172.         JMP     CHAR
  173. PDONE:  MOV     OLD_SI,SI       ;Save SI for the next path.
  174.         MOV     BYTE PTR [DI],'\'       ;Add '\' to both paths
  175.         MOV     BYTE PTR [BX],'\'
  176.         INC     BX                      ;Move BX on for next time
  177.         MOV     OLD_BX,BX               ;And save it.
  178.         INC     DI                      ;Move to next location at 5CH and
  179.         CALL    PUT                     ;Put '*.*'0 there to find all files.
  180.         MOV     DX,5CH                  ;Start the search for all files in
  181.         MOV     AH,4EH                  ; the new path.
  182.         MOV     CX,0                    ;Set the file attribute to 0
  183.         INT     21H
  184.         CMP     AL,18                   ;Did we find any new files in new path?
  185.         JE      NEXT_PATH               ;No, get the next path.
  186. NEW:    CMP     EXTRA_PATHS,1           ;Yes,Move found filename to DBH area to
  187.         JNE     END                     ; read it in-only if DBH area is active
  188.         MOV     BX,OLD_BX               ; (i.e. Extra_Paths=1). Restore BX
  189.         MOV     SI,0CDH                 ;And point to found filename in DTA
  190. CLOOP:  INC     SI                      ;Next letter from found filename
  191.         MOV     AH,[SI]                 ;Move it to the DBH area so we can read
  192.         MOV     [BX],AH                 ; in the file (needs pathname\filename)
  193.         INC     BX                      ;Next character in 5CH area.
  194.         CMP     BYTE PTR [SI],0         ;Is this the last character?
  195.         JNE     CLOOP                   ;Nope, get next one
  196. END:    RET                             ;After path & filename assembled, return
  197. FIND_FILE       ENDP
  198.  
  199. READ_FILE       PROC    NEAR    ;Looks for filename at CEH or DBH & reads it
  200.         PUSH    AX              ;Push everything to save it.
  201.         PUSH    BX
  202.         PUSH    CX
  203.         PUSH    DX
  204.         MOV     DX,0DBH         ;Try the DBH area
  205.         CMP     EXTRA_PATHS,1   ;Has it been used?
  206.         JE      OK              ;Yes
  207.         MOV     DX,0CEH  ;No, not using paths yet, use filename only, at CEH
  208. OK:     MOV     AX,3D00H        ;Prepare for file reading
  209.         INT     21H             ;And do so.
  210.         MOV     BX,AX           ;Move file handle into BX to read
  211.         MOV     DX,OFFSET PATHS+300     ;Read into data area at Paths+300 bytes
  212.         MOV     CX,LEN                  ;Read the full file's length in bytes
  213.         MOV     AH,3FH                  ;Read it in at last
  214.         INT     21H
  215.         MOV     NUMBER,AX               ;Number of bytes actually read.
  216.         MOV     AH,3EH                  ;Close file
  217.         INT     21H
  218.         MOV     BX,OFFSET PATHS+300     ;Clean up the Word Star high bit.
  219.         MOV     CX,LEN                  ;For the full file
  220.         CALL    WS                      ;Strip high bit for ws
  221.         POP     DX                      ;Pop evrything and return
  222.         POP     CX
  223.         POP     BX
  224.         POP     AX
  225.         RET                             ;Fin of Read_File
  226. READ_FILE       ENDP
  227. PATHS:                                  ;Here's the end of program marker
  228.  
  229. CODE_SEG        ENDS
  230.         END     ENTRY                   ;End 'Entry' so DOS starts at 'Entry'
  231.